<?php

namespace App\Http\Controllers\Web\VoteCandidate;

use App\App\Services\StorageService;
use App\App\Services\SyncCacheService;
use App\App\Services\Web\UserService;
use App\Exceptions\ExceptionCode;
use App\Http\Controllers\Controller;
use App\Models\Activity\ActivityRepository;
use App\Models\Activity\ActivityService;
use App\Models\Enroll\Enroll;
use App\Models\Resource\Resource;
use App\Models\Resource\ResourceService;
use App\Models\User\User;
use App\Models\VoteCandidate\VoteCandidate;
use Illuminate\Http\Request;
use App\Models\VoteCandidate\VoteCandidateRepository;
use App\Models\VoteGroup\VoteGroupRepository;
use App\Models\VoteRecord\VoteRecordRepository;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Maatwebsite\Excel\Facades\Excel;
use App\Models\VoteCandidate\VoteCandidateService;

class VoteCandidateController extends Controller
{
    public function candidate(
        Request $request,
        UserService $userService,
        StorageService $storageService,
        VoteCandidateRepository $voteCandidateRepository,
        VoteGroupRepository $voteGroupRepository,
        ResourceService $resourceService
    )
    {
        $loginUser = $userService->getLoginUser();

        //模拟活动ID
        $activity_id = md5($loginUser['id'] . time());

        if ($request->isMethod('post')) {
            $this->validate($request, [
                'actorName'          => 'required',
                'actorBackgroundImg' => 'required',
                'actorType'          => 'required',
                'actorDescription'   => 'required',
                'actorIntroduce'     => 'required',
            ], [
                'actorName.required'          => '请填写名称',
                'actorBackgroundImg.required' => '请上传缩略图',
                'actorType.required'          => '请选择展示类型',
                'actorDescription.required'   => '请输入描述',
                'actorIntroduce.required'     => '请输入详细介绍',
            ]);
            $input = $request->request->all();

            if (!empty($input['id']) && !empty($input['activity_id'])) {
                $activity_id = $input['activity_id'];
                //                'alioss://tmp/20170509/00/20170509005249294837.jpg';
                if ($input['actorType'] == VoteCandidate::TYPE_AUDIO) {
                    $resource_id = $input['actorAudio'];
                } elseif ($input['actorType'] == VoteCandidate::TYPE_VIDEO) {
                    $resource_id = $input['actorVideo'];
                } else {
                    $resource_id = '';
                }
                $content = $input['actorIntroduce'];
                $voteCandidate = $voteCandidateRepository->findById($input['id']);
                if ($voteCandidate && $voteCandidate->from == 3) {
                    $content = \GuzzleHttp\json_decode($voteCandidate->content, true);
                    if (isset($content['text'])) {
                        $content['text'] = $input['actorIntroduce'];
                    }
                    $content = \GuzzleHttp\json_encode($content);
                }
                $data = [
                    'activity_id' => $activity_id,
                    'type'        => $input['actorType'],
                    'title'       => $input['actorName'],
                    'group_id'    => $input['actorGroup'],
                    'description' => $input['actorDescription'],
                    'content'     => $content,
                    'weight'      => Arr::get($input, 'weight', 0),
                    'status'      => Arr::get($input, 'status', 0),
                    'cover_url'   => Arr::get($input, 'actorBackgroundImg', ''),
                    'resource_id' => $resource_id,
                ];
                if (substr($input['actorBackgroundImg'], 0, 5) == 'alios') {
                    if (isset($data['cover_url'])) {
                        $data['cover_url'] = $storageService->tomedia($input['actorBackgroundImg']);
                    }
                }
                $res = $voteCandidateRepository->update($data, ['id' => $input['id']]);
                if ($res) {
                    $res = $voteCandidateRepository->findById($input['id']);
                }
            } else {
                $activity_id = !empty($input['activity_id']) ? $input['activity_id'] : $activity_id;
                $count = $voteCandidateRepository->getMaxOrderId($input['actorGroup'], $activity_id);
                $code = $voteCandidateRepository->getMaxCode($activity_id);
                if ($input['actorType'] == VoteCandidate::TYPE_AUDIO) {
                    $resource_id = $input['actorAudio'];
                } elseif ($input['actorType'] == VoteCandidate::TYPE_VIDEO) {
                    $resource_id = $input['actorVideo'];
                } else {
                    $resource_id = '';
                }
                $data = [
                    'activity_id'  => $activity_id,
                    'type'         => $input['actorType'],
                    'title'        => $input['actorName'],
                    'cover_url'    => !empty($input['actorBackgroundImg']) ? $storageService->storeAsImage($storageService->tomedia($input['actorBackgroundImg']))['original'] : '',
                    'group_id'     => $input['actorGroup'],
                    'description'  => $input['actorDescription'],
                    'content'      => $input['actorIntroduce'],
                    'weight'       => Arr::get($input, 'weight', 0),
                    'status'       => Arr::get($input, 'status', 0),
                    'resource_id'  => $resource_id,
                    'votes_number' => 0,
                    'order_id'     => intval($count) + 1,
                    'code'         => intval($code) + 1,
                    'from'         => Enroll::FROM_ADD,
                ];
                $res = $voteCandidateRepository->create($data);
            }

            if ($res) {
                $resource = [
                    'resource_id'  => $resource_id,
                    'candidate_id' => $res->id,
                    'type'         => $input['actorType'],
                ];
                if ($input['actorType'] == VoteCandidate::TYPE_IMAGE) {
                    $resource['resource_url'] = isset($data['cover_url']) ? $data['cover_url'] : $res->cover_url;
                }

                //$resourceService->create($resource);

                return $this->respondJson(['activity_id' => $activity_id]);
            } else {
                return $this->respondJson([
                    'select' => $res,
                ]);
            }
        } else {
            $order = $request->query->get('order');
            $activity_idGet = $request->query->get('activity_id');
            $group_id = $request->query->get('group_id', 'all');
            $activity_id = !empty($activity_idGet) ? $activity_idGet : $activity_id;
            $groups = $voteGroupRepository->findByActivityId($activity_id);

            $groupData = [];
            if ($groups->count() > 0) {
                foreach ($groups as $group) {
                    if (isset($group->id)) {
                        $groupData[$group->id] = $group->title;
                    }
                }
            }

            if ($group_id == '暂未添加分组' || empty($group_id)) {
                $group_id = 'all';
            }

            $voteCandidates = $voteCandidateRepository->getItemsByGroup($group_id, $activity_id, 0);
            if ($voteCandidates->count() > 0) {
                foreach ($voteCandidates as $of => $voteCandidate) {
                    $voteCandidates[$of]->cover_url = $storageService->tomedia($voteCandidate->cover_url);
                    $voteCandidates[$of]->group_title = isset($groupData[$voteCandidate->group_id]) ? $groupData[$voteCandidate->group_id] : '无';
                    //$voteCandidate->resource_url = array_column($voteCandidate->resource->toArray(), 'resource_url');
                    //$voteCandidate->resource_url = [$voteCandidate->resource->value('resource_url')];
                    $voteCandidates[$of]->resource_url = [
                        Resource::query()->where('resource_id', $voteCandidate->resource_id)
                            ->orderBy('id', 'DESC')
                            ->value('resource_url'),
                    ];
                }
            }

            return $this->respondJson([
                'data'        => $voteCandidates,
                'activity_id' => $activity_id,
            ]);
        }
    }

    /**
     * @param Request                 $request
     * @param VoteCandidateRepository $voteCandidateRepository
     */
    public function delete(Request $request, VoteCandidateRepository $voteCandidateRepository)
    {
        $input = $request->request->all();
        $id = $input['id'];

        if (empty($id)) {
            return $this->respondJson([
                'message' => 'ID不存在',
            ]);
        }

        $ids = json_decode($id);

        if (!is_array($ids)) {
            $data = $voteCandidateRepository->findById($id);
            if (!$data) {
                return $this->respondJson([
                    'message' => '数据不存在',
                ]);
            }
            $ids = [$id];
        }

        $res = $voteCandidateRepository->softDelete($ids);
        if ($res) {
            return $this->respondJson([
                'message' => '删除成功',
            ]);
        } else {
            return $this->respondJson([
                'message' => '删除失败！请重新删除',
            ]);
        }
    }


    /**
     * @param Request                 $request
     * @param VoteCandidateRepository $voteCandidateRepository
     */
    public function get(Request $request, VoteCandidateRepository $voteCandidateRepository)
    {
        $input = $request->request->all();
        $id = $input['id'];
        if (empty($id)) {
            return $this->respondJson([
                'message' => 'ID不存在',
            ]);
        }

        $data = $voteCandidateRepository->findById($id);

        return $this->respondJson([
            'message' => '删除成功',
        ]);
    }

    public function group(Request $request, UserService $userService, VoteGroupRepository $voteGroupRepository)
    {
        $loginUser = $userService->getLoginUser();

        //模拟活动ID
        $activity_id = md5($loginUser['id'] . time());

        if ($request->isMethod('post')) {
            $input = $request->request->all();
            $group = !empty($input['data']) ? json_decode($input['data'], true) : '';

            $activity_id = !empty($input['activity_id']) ? $input['activity_id'] : $activity_id;

            if (!is_array($group)) {
                return $this->respondJson([
                    'message' => '无效请求',
                ]);
            }
            $oldGroupData = $voteGroupRepository->where(['activity_id' => $activity_id]);

            $res = [];
            if ($oldGroupData->toArray()) {

                //已有的分组
                foreach ($oldGroupData as $list) {
                    $oldData[$list->id] = $list->toArray();
                }
                $newGroupData = [];
                foreach ($group as $i => $v) {
                    if (!isset($v['group_id'])) { //对比新旧组
                        $data = [
                            'title'       => $v['title'],
                            'type'        => 1,
                            'activity_id' => $activity_id,
                            'order_id'    => $i,
                        ];
                        $groupId = $voteGroupRepository->create($data);
                        $data['group_id'] = $groupId;
                        $res[$i] = $data;
                    } else {//更新名称

                        $newGroupData[$v['group_id']] = $v;
                        //存在，名称，排序不同 ,更新
                        $voteGroupRepository->update(['title' => $v['title'], 'order_id' => $i], ['id' => $v['group_id']]);
                        $oldData[$v['group_id']]['title'] = $v['title'];
                        $oldData[$v['group_id']]['order_id'] = $i;
                        $oldData[$v['group_id']]['group_id'] = $v['group_id'];

                        $res[$i] = $oldData[$v['group_id']];
                    }
                }

                //删除不要的数据
                $newID = array_keys($newGroupData);
                $oldID = array_keys($oldData);
                $deleteIds = array_diff($oldID, $newID);
                foreach ($deleteIds as $i => $id) {
                    $voteGroupRepository->delete(['id' => $id]);
                }
            } else {
                $voteGroupRepository->delete(['activity_id' => $activity_id]);
                foreach ($group as $i => $v) {
                    $data = [
                        'title'       => $v['title'],
                        'type'        => 1,
                        'activity_id' => $activity_id,
                        'order_id'    => $i,
                    ];
                    $groupId = $voteGroupRepository->create($data);
                    $data['group_id'] = $groupId;
                    $res[$i] = $data;
                }
            }


            return $this->respondJson([
                'data'        => $res,
                'activity_id' => $activity_id,
            ]);
        } else {
            return $this->respondJson([
                'message' => '无效请求',
            ]);
        }
    }

    /**
     * @param Request                 $request
     * @param VoteRecordRepository    $voteRecordRepository
     * @param VoteCandidateRepository $voteCandidateRepository
     */
    public function getRecord(Request $request, VoteRecordRepository $voteRecordRepository, VoteCandidateRepository $voteCandidateRepository)
    {
        $candidate_id = $request->request->get('candidate_id');

        $dataCandidate = $voteCandidateRepository->findById($candidate_id);

        if (empty($dataCandidate)) {
            return abort(404);
        }

        $recordData = $voteRecordRepository->exportRecord($candidate_id);

        $data = [];
        if (!empty($recordData)) {
            $recordData = $recordData->toArray();
            foreach ($recordData as $lists) {
                $res['name'] = $lists->name;
                $res['ip'] = $lists->ip;
                $res['voteTime'] = $lists->voted_at;
                $data[] = $res;
            }
        }

        $filename = '【' . $dataCandidate->title . '】投票纪录' . date('Y-m-d H:i:s');

        Excel::create($filename, function ($excel) use ($data) {
            $excel->sheet('活动参与者', function ($sheet) use ($data) {
                $sheet->fromArray($data);
            });
        })->download('xlsx');
    }


    /**
     *  单个候选人的投票纪录
     *
     * @param Request                 $request
     * @param VoteCandidateRepository $voteCandidateRepository
     * @param StorageService          $storageService
     *
     * @return \Illuminate\Http\JsonResponse
     * @todo a
     */
    public function getRecordData(Request $request, VoteCandidateRepository $voteCandidateRepository, StorageService $storageService)
    {
        $activity_id = $request->query->get('activity_id');

        $res = $voteCandidateRepository->getByActivityId($activity_id);
        foreach ($res as &$list) {
            $list->cover_url = $storageService->tomedia($list->cover_url);
        }

        //        return $this->respondJson([
        //            'candidates' => $res->toArray(),
        //        ]);

        //        $dataRes=['total'=>1,'rows'=>$res];
        echo json_encode($res);
        die;
    }

    /**
     * 展示投票纪录
     *
     * @param Request $request
     *
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function showRecordViews(Request $request)
    {
        $activity_id = $request->query->get('activity_id');

        return view('web.voteCandidate.votedatalist', ['activity_id' => $activity_id]);
    }

    public function getVoteRecords(Request $request, ActivityService $activityService)
    {
        $activity_id = $request->query->get('activity_id');

        $activity = $activityService->findOne($activity_id);

        return view('web.voteCandidate.voteRecordList', ['activity_id' => $activity_id, 'activity' => $activity]);
    }


    /**
     *  导出候选人
     *
     * @param Request                 $request
     * @param ActivityRepository      $activityRepository
     * @param VoteGroupRepository     $voteGroupRepository
     * @param VoteCandidateRepository $voteCandidateRepository
     * @param VoteRecordRepository    $recordRepository
     */
    public function downValidationData(Request $request, ActivityRepository $activityRepository, VoteGroupRepository $voteGroupRepository, VoteCandidateRepository $voteCandidateRepository, VoteRecordRepository $recordRepository)
    {
        $activity_id = $request->query->get('activity_id');
        $dataRes = $voteCandidateRepository->where(['activity_id' => $activity_id]);

        $activity = $activityRepository->findOne($activity_id);

        if (null === $activity) {
            return;
        }
        if(!$dataRes->count()){
            echo '无投票数据';
            exit();
        }
        $dataEnroll = [];
        $data = [];
        $voteCandidateId = [];
        if ($dataRes) {
            foreach ($dataRes as $list) {
                $groups = $voteGroupRepository->findById($list->group_id);
                $res['组名'] = !empty($groups) ? $groups->title : '无';
                $res['候选者'] = $list->title;
//          $res['内容'] = $list->content;
                $res['描述'] = $list->description;
                $res['实际票数'] = $list->votes_number - $list->intervention_number;
                $res['干预票数'] = $list->intervention_number;
                $res['总票数'] = ($list->votes_number < 0) ? 0 : $list->votes_number;
                $resEnroll = $res;
                if ($list->from == Enroll::FROM_ENROLLS_JSON) {
                    $content = \GuzzleHttp\json_decode($list->content, true);
                    if (!empty($content)) {
                        if (isset($content['text']) && $content['text']) {
                            foreach ($content['text'] as $index => $value) {
                                $resEnroll[$index] = $value;
                            }
                        }
                        if (isset($content['video']) && $content['video']) {
                            $resEnroll['视频'] = '';
                            foreach ($content['video'] as $key => $v) {
                                $resEnroll['视频'] .= $v['resource_url'] . "\r\n";
                            }
                        }
                        if (isset($content['img']) && $content['img']) {
                            $resEnroll['图片'] = implode("\r\n", $content['img']);
                        }
                    }
                    $dataEnroll[] = $resEnroll;
                } else {
                    $res['内容'] = strip_tags($list->content);
                    $data[] = $res;
                }
                $voteCandidateId[] = $list->id;
                $res = $resEnroll = [];
            }
        }
        $dbRecord = $recordRepository->exportRecord($voteCandidateId);
        $dataRecord = [];
        $res = [];
        if ($dbRecord) {
            foreach ($dbRecord as $record) {
                $res['openid'] = $record->openid;
                $res['来源'] = $record->source;
                $res['投票项'] = $record->title;
                $res['投票人'] = $record->username;
                $res['手机'] = $record->mobile;
                $res['投票时间'] = date('Y-m-d H:i:s', $record->voted_at);
                $dataRecord[] = $res;
            }
        }

        $filename = '【' . $activity->name . '】活动参与者' . date('Y-m-d H:i:s');

        Excel::create($filename, function ($excel) use ($data, $dataEnroll, $dataRecord) {
            if ($dataEnroll) {
                $excel->sheet('报名审核投票项', function ($sheet) use ($dataEnroll) {
                    $sheet->fromArray($dataEnroll);
                });
            }
            if ($data) {
                $excel->sheet('活动自建投票项', function ($sheet) use ($data) {
                    $sheet->fromArray($data);
                });
            }
            if ($dataRecord) {
                $excel->sheet('活动参与者', function ($sheet) use ($dataRecord) {
                    $sheet->fromArray($dataRecord);
                });
            }
        })->download('xlsx');
    }

    public function intervene(Request $request, VoteCandidateService $voteCandidateService, SyncCacheService $syncCacheService)
    {
        $itemID = $request->input('item_id');
        if ($itemID) {
            $item = $voteCandidateService->getItemById($itemID);
            if (!empty($item)) {
                if ($request->isMethod('post')) {
                    $addInterventionNumber = intval($request->input('intervention_number'));
                    if (empty($addInterventionNumber)) {
                        $addInterventionNumber = 0;
                    }
                    $voteNumber = $item->votes_number;
                    $interventionNumber = $item->intervention_number;
                    $item->intervention_number = $addInterventionNumber;
                    $item->votes_number = $voteNumber - $interventionNumber + $addInterventionNumber;
                    $result = $item->save();
                    if ($result) {
                        $changeNumber = $addInterventionNumber - $interventionNumber;
                        $syncCacheService->changeRanking($item->activity_id, $itemID, $changeNumber);
                        $syncCacheService->changeScore($item->activity_id, $itemID, $changeNumber);

                        return $this->respondJson(['code' => 200, 'message' => '修改成功']);
                    } else {
                        return $this->respondJson(['code' => 300, 'message' => '修改失败']);
                    }
                } else {
                    return $this->respondJson(['code' => 200, 'message' => '获取成功', 'data' => $item->intervention_number, 'votes_number' => $item->votes_number]);
                }
            } else {
                return $this->respondJson(['code' => 300, 'message' => '没有对应的投票项']);
            }
        } else {
            return $this->respondJson(['code' => 300, 'message' => '请求参数错误']);
        }
    }

    public function shelvesEdit(Request $request, VoteCandidateService $voteCandidateService)
    {
        $id = $request->input('id');
        $status = $request->input('status');
        $result = $voteCandidateService->modifyCandidate(['status' => $status], ['id' => $id]);
        if ($result) {
            return $this->respondJson('操作成功');
        } else {
            return $this->respondJson('操作失败');
        }
    }
}
